#include "stm32f10x.h"                  // Device header
#include "BH1750.h"
#include "Delay.h"
#include "OLED.h"

uint8_t BUF[8];		//接收数据缓存区
int mcy;     		//进位标志
float temp1;
float temp2;

/***开始信号***/
void BH1750_Start()
{
	GPIO_SetBits(GPIOA, GPIO_Pin_3);	//拉高数据线
	GPIO_SetBits(GPIOA, GPIO_Pin_2);	//拉高时钟线
	Delay_us(5);             //延时
	GPIO_ResetBits(GPIOA, GPIO_Pin_3);	//产生下降沿
	Delay_us(5);             //延时
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);	//拉低时钟线
//	SDA=1;                   
//	SCL=1;                   
//	Delay_us(5);             //延时
//	GPIO_ResetBits(bh1750_PORT, sda);           
//	Delay_us(5);             //延时
//	GPIO_ResetBits(bh1750_PORT, scl);           
}

/*****停止信号******/
void BH1750_Stop()
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_3);	//拉低数据线
	GPIO_SetBits(GPIOA, GPIO_Pin_2);	//拉高时钟线
	Delay_us(5);                        //延时
	GPIO_SetBits(GPIOA, GPIO_Pin_3);	//产生上升沿
	Delay_us(5);                 			//延时
//	SDA=0;                                  
//	SCL=1;                                  //拉高时钟线
//	Delay_us(5);                            //延时
//	GPIO_SetBits(bh1750_PORT, sda);         //产生上升沿
//	Delay_us(5);                 			//延时
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK(int ack)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStruct);  
	
	if(ack == 1)   //写应答信号
		GPIO_SetBits(GPIOA, GPIO_Pin_3);
	else if(ack == 0)
		GPIO_ResetBits(GPIOA, GPIO_Pin_3); 
	else
		return;			
	GPIO_SetBits(GPIOA, GPIO_Pin_2);     //拉高时钟线
	Delay_us(5);                 //延时
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);      //拉低时钟线
	Delay_us(5);                //延时
}

/**************************************
接收应答信号
**************************************/
int BH1750_RecvACK()
{
	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;  /*这里一定要设成输入上拉，否则不能读出数据*/
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_SetBits(GPIOA, GPIO_Pin_2);            //拉高时钟线
	Delay_us(5);                 //延时	
	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)==1)//读应答信号
		mcy = 1 ;  
	else
		mcy = 0 ;				
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);                    //拉低时钟线
	Delay_us(5);                 //延时
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	return mcy;
}

/**************************************
向IIC总线发送一个字节数据
**************************************/
void BH1750_SendByte(uint8_t dat)
{
	uint8_t i;
	for (i=0; i<8; i++)         //8位计数器
	{
		if( 0X80 & dat )
		  GPIO_SetBits(GPIOA,GPIO_Pin_3);
		else
		  GPIO_ResetBits(GPIOA,GPIO_Pin_3);
			dat <<= 1;
		GPIO_SetBits(GPIOA, GPIO_Pin_2);               //拉高时钟线
		Delay_us(5);             //延时
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);                //拉低时钟线
		Delay_us(5);            //延时
	}
	
	BH1750_RecvACK();
}

uint8_t BH1750_RecvByte()
{
	uint8_t i;
	uint8_t dat = 0;
	uint8_t bit;

	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;   /*这里一定要设成输入上拉，否则不能读出数据*/
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct );
	
	GPIO_SetBits(GPIOA,GPIO_Pin_3);          //使能内部上拉,准备读取数据,
	for (i=0; i<8; i++)         //8位计数器
	{
		dat <<= 1;
		GPIO_SetBits(GPIOA, GPIO_Pin_2);;               //拉高时钟线
		Delay_us(5);             //延时
			
		if( SET == GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3))
			bit = 0X01;
		else
			bit = 0x00;  
		dat |= bit;             //读数据    
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);;                //拉低时钟线
		Delay_us(5);            //延时
	}		
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStruct );
	return dat;
}



void Single_Write_BH1750(uint8_t REG_Address)
{
  BH1750_Start();                  //起始信号
  BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
  BH1750_SendByte(REG_Address);    //内部寄存器地址，请参考中文pdf22页 
//  BH1750_SendByte(REG_data);       //内部寄存器数据，请参考中文pdf22页 
  BH1750_Stop();                   //发送停止信号
}

//初始化BH1750，根据需要请参考pdf进行修改****
void BH1750_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	/*开启GPIOB的外设时钟*/ 
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); 
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 ;
	GPIO_Init(GPIOA,&GPIO_InitStruct); 

	Single_Write_BH1750(0x01);  
	Delay_ms(180);            //延时180ms
}

//连续读出BH1750内部数据
void mread(void)
{   
	uint8_t i;	
	BH1750_Start();                          //起始信号
	BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号

	for (i=0; i<3; i++)                      //连续读取6个地址数据，存储中BUF
	{
		BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
		if (i == 3)
		{
		  BH1750_SendACK(1);                //最后一个数据需要回NOACK
		}
		else
		{		
		  BH1750_SendACK(0);                //回应ACK
		}
	}
	BH1750_Stop();                          //停止信号
	Delay_ms(5);
}

void BH1750_read(void)
{
	int dis_data;                       //变量	

	Single_Write_BH1750(0x01);   // power on
	Single_Write_BH1750(0x10);   // H- resolution mode
	Delay_ms(180);            //延时180ms
	
	mread();       //连续读出数据，存储在BUF中
	
	dis_data=BUF[0];
	dis_data=(dis_data<<8)+BUF[1]; //合成数据 
	
	temp1=dis_data/1.2;
	temp2=10*dis_data/1.2;	
	temp2=(int)temp2%10;
}












